﻿using System;
using System.Collections;
using System.Linq;
using System.Text;
using CRUD.InterfaceDAO;
using CapaNegocios;
using GestionadorBaseDatos;
using CapaGestion.Spring;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using iTextSharp.text;
using iTextSharp.text.pdf;
using System.IO;


namespace CapaGestion
{
    /// <summary>
    /// Gestiona las apuestas realizadas por un usuario
    /// </summary>
    public class GestionarApuesta : IGestionApuesta
    {
        #region atributos
        private IDaoApuesta daoApuesta;
        private IDaoPago daoPago;
        private IDaoFormaPago daoFormaPago;
        private IDaoParticipante daoParticipante;
        private IDaoProporcion daoProporcion;
        private IDaoEvento daoEvento;
      
        private IList pagoUsuario = new ArrayList();
        #endregion

        #region metodos

        /// <summary>
        /// Gestiona una consulta donde devuelve todos los datos de una apuesta y 
        /// le asocia una lista de quienes asociaron un pago
        /// </summary>
        public IList GetAll()
        {
            //aqui
            return (insertarPagos(daoApuesta.GetAll()));
        }
        /// <summary>
        /// Procedimiento para updatear status de un evento
        /// </summary>
        /// <param name="even"></param>
        public void UpdateEvento(Evento even)
        {
            daoEvento.Update(even);
        }
        /// <summary>
        /// Gestiona una consulta donde devuelve una apuesta por pago y 
        /// le asocia una lista de quienes asociaron un pago
        /// </summary>
        public IList GetByPago(Pago idPago)
        {//aqui va el otro
            return (insertarPagos(daoApuesta.GetByPago(idPago)));
        }

        /// <summary>
        /// Gestiona una consulta donde devuelve una apuesta por evento
        /// </summary>
        public IList GetByEvento(Evento idevento)
        {
            return (insertarPagos(daoApuesta.GetByEvento(idevento)));
        }

        /// <summary>
        /// Gestiona una consulta donde devuelve una apuesta dado su ID 
        /// </summary>
        public IList GetById(string nickname)
        {
            return insertarPagos(daoApuesta.GetById(nickname));
        }
        /// <summary>
        /// procedimiento que llama a la insercion de una nueva apuesta
        /// </summary>
        /// <param name="apuesta"></param>
        public void Insert(Apuesta apuesta)
        {
            daoApuesta.Insert(apuesta);
        }
        /// <summary>
        /// Gestiona la insercion del pago de la apuesta realizada
        /// </summary>
        public IList insertarPagos(IList agregarDatos)
        {
            int numeroCampos = agregarDatos.Count;
            IList apuestaDevuelta = new ArrayList();
            for (int i = 0; i < numeroCampos; i++)
            {
                Apuesta agregar = (Apuesta)agregarDatos[i];
                agregar.PagoAsociado = daoPago.GetPagosByUserAndId(((Apuesta)agregarDatos[i]).PagoAsociado);
                agregar.ProporcionAsociado = daoProporcion.GetByIds(((Apuesta)agregarDatos[i]).ProporcionAsociado);
                agregar.PagoAsociado.FormaPagoAsociado = daoFormaPago.GetById(((Apuesta)agregarDatos[i]).PagoAsociado.FormaPagoAsociado);
                agregar.ProporcionAsociado.Participante = daoParticipante.GetById(((Apuesta)agregarDatos[i]).ProporcionAsociado.Participante.IdParticipante);
                agregar.ProporcionAsociado.EventoAsociado = daoEvento.GetById(((Apuesta)agregarDatos[i]).ProporcionAsociado.EventoAsociado.IdEvento);
                agregar.ProporcionAsociado.EventoAsociado.Proporciones = daoProporcion.GetByEvento(agregar.ProporcionAsociado.EventoAsociado.IdEvento);
                foreach (Proporcion p in agregar.ProporcionAsociado.EventoAsociado.Proporciones)
                {
                    p.Participante = daoParticipante.GetById(p.Participante.IdParticipante);
                }
                apuestaDevuelta.Add(agregar);
            }
            return apuestaDevuelta;

        }

        /// <summary>
        /// procedimiento para agregar los valores de los objetos asociadoas a la apuesta
        /// </summary>
        /// <param name="agregarDatos">tipo de apuesta que contiene la informacion basica para rellenar luego</param>
        /// <returns></returns>
        public Apuesta apuestaDatos(Apuesta agregarDatos)
        {
            agregarDatos.PagoAsociado = daoPago.GetPagosByUserAndId(agregarDatos.PagoAsociado);
            agregarDatos.PagoAsociado.FormaPagoAsociado = daoFormaPago.GetById(agregarDatos.PagoAsociado.FormaPagoAsociado);
            agregarDatos.ProporcionAsociado = daoProporcion.GetByIds(agregarDatos.ProporcionAsociado);
            agregarDatos.ProporcionAsociado.Participante = daoParticipante.GetById(agregarDatos.ProporcionAsociado.Participante.IdParticipante);
            agregarDatos.ProporcionAsociado.EventoAsociado = daoEvento.GetById(agregarDatos.ProporcionAsociado.EventoAsociado.IdEvento);
            return agregarDatos;
        }
        #endregion

        /// <summary>
        /// metodo para obtener un participante dado su id
        /// </summary>
        /// <param name="part">tipo de dato PArticipante que posee la informacion basica para la busqueda</param>
        /// <returns></returns>
        public Participante getParticipanteId(Participante part)
        {

            return daoParticipante.GetById(part);
        }
        /// <summary>
        /// metodo para obtener la forma de pago de una apuesta
        /// </summary>
        /// <param name="part">Forma de pago con el id a buscar</param>
        /// <returns></returns>
        public FormaPago getFormaPagoId(FormaPago part)
        {

            return daoFormaPago.GetById(part);
        }
        /// <summary>
        /// obtiene una forma de pago dado su nombre
        /// </summary>
        /// <param name="part">contiene el nombre de la forma de pago a buscar</param>
        /// <returns></returns>
        public FormaPago getFormaPagoNombre(FormaPago part)
        {

            return daoFormaPago.GetFormaPagoByNombre(part);
        }
        /// <summary>
        /// Obtiene lista con las apuestas donde el usuario a resultado ganador
        /// </summary>
        /// <param name="nickname">nickname del usuario a buscar</param>
        /// <returns>Lista con apuestas ganadoras</returns>
        public IList getGanancias(string nickname)
        {
            IList apuestas = insertarPagos(daoApuesta.GetById(nickname));
            IList apuestasGanadas = new ArrayList();
               foreach (Apuesta apuesta in apuestas)
            {
                int a1 = int.Parse(((Proporcion)apuesta.ProporcionAsociado.EventoAsociado.Proporciones[0]).Ganador);
                int a2 = int.Parse(((Proporcion)apuesta.ProporcionAsociado.EventoAsociado.Proporciones[1]).Ganador);
                if (a1 > a2)
                {
                    if (((Proporcion)apuesta.ProporcionAsociado.EventoAsociado.Proporciones[0]).Participante.IdParticipante == apuesta.ProporcionAsociado.Participante.IdParticipante)
                    {
                        apuestasGanadas.Add(apuesta);
                    }
                }
                else if (a1 < a2)
                {
                    if (((Proporcion)apuesta.ProporcionAsociado.EventoAsociado.Proporciones[1]).Participante.IdParticipante == apuesta.ProporcionAsociado.Participante.IdParticipante)
                    {
                        apuestasGanadas.Add(apuesta);
                    }
                }
                
            }
               return apuestasGanadas;
        }
        /// <summary>
        /// procedimiento para enviar correo y crear la factura luego de apostar
        /// </summary>
        /// <param name="usuario">contiene los datos del usuario</param>
        /// <param name="apuesta">contiene los datos de la apuesta</param>
        /// <param name="evento">contiene los datos del evento</param>
        /// <param name="participante">contiene los datos del participante que se aposto</param>
        /// <param name="proporcion">contiene los datos de la proporcion del evento</param>
        public void EnviarCorreoConFactura(Usuario usuario, Apuesta apuesta, Evento evento, Participante participante, Proporcion proporcion)
        {
            //Se establece la cadena de texto con la ubicación del archivo a adjuntar 
            string ruta = "C:\\new\\" + usuario.Nickname + apuesta.IdApuesta + ".pdf";
            apuesta.PagoAsociado.FormaPagoAsociado = daoFormaPago.GetById(apuesta.PagoAsociado.FormaPagoAsociado);
            Document document = new Document();
            PdfWriter.GetInstance(document, new FileStream(ruta, FileMode.OpenOrCreate));
            document.Open();

            //Se crea una imagen para agregarla a la factura.
            iTextSharp.text.Image jpg = iTextSharp.text.Image.GetInstance("C:\\new\\Foto.jpg");
            jpg.Alignment = iTextSharp.text.Image.LEFT_ALIGN;

            iTextSharp.text.Table tableTitulo = new iTextSharp.text.Table(3);

            tableTitulo.BorderWidth = 0;
            tableTitulo.BorderColor = new Color(0, 0, 255);
            tableTitulo.Border = 0;
            tableTitulo.Padding = 2;
            tableTitulo.Spacing = 2;

            Cell imagen = new Cell();
            imagen.Add(jpg);
            tableTitulo.AddCell(imagen);

            //Paragraph propaganda = new Paragraph("Se acabo lo que quedaba");
            //propaganda.Alignment = iTextSharp.text.Cell.ALIGN_CENTER;

            //tableTitulo.AddCell(propaganda);

            Cell datosFactura = new Cell(new Paragraph("Factura Nro : " + apuesta.IdApuesta + "\n" + "Fecha: " + DateTime.Now));
            tableTitulo.AddCell(datosFactura);
            tableTitulo.EndHeaders();
            document.Add(tableTitulo);

            // Se hace un salto de linea en el pdf
            document.Add(new Paragraph("\n\r"));

            //Se agregan los datos del cliente
            Chunk chunk = new Chunk("Datos del Cliente :", FontFactory.GetFont("ARIAL", 12, iTextSharp.text.Font.UNDERLINE));
            document.Add(chunk);

            document.Add(new Paragraph("Nombre Completo: " + usuario.Nombre + " " + usuario.Apellido));
            document.Add(new Paragraph("Telefono: " + usuario.Telefono));
            document.Add(new Paragraph("Nombre de usuario Kamalde: " + usuario.Nickname));
            document.Add(new Paragraph("Direccion: " + usuario.Direccion + ", " + usuario.Ciudad + ", " + usuario.Pais));

            // Se hace un salto de linea en el pdf
            document.Add(new Paragraph("\n\r"));

            // Estilos para las Celdas      
            Font font_celdas = FontFactory.GetFont("ARIAL", 9, iTextSharp.text.Font.HELVETICA);
            Font font_titulo_tabla = FontFactory.GetFont("ARIAL", 12, Font.BOLD, new Color(0, 0, 0));

            //Creacion de la tabla de detalles de la factura
            iTextSharp.text.Table table = new iTextSharp.text.Table(5);

            table.BorderWidth = 0;
            table.BorderColor = new Color(0, 0, 0);
            table.Padding = 1;
            table.Spacing = 1;

            Cell titulo = new Cell(new Phrase("Detalle de la Factura", font_titulo_tabla));
            titulo.HorizontalAlignment = 1;
            titulo.Header = true;

            titulo.Colspan = 5;
            table.AddCell(titulo);
            table.AddCell(new Phrase("Evento", font_celdas));
            table.AddCell(new Phrase("Opcion Seleccionada", font_celdas));
            table.AddCell(new Phrase("Proporcion", font_celdas));
            table.AddCell(new Phrase("Monto Apostado", font_celdas));
            table.AddCell(new Phrase("Forma de Pago", font_celdas));
            table.EndHeaders();


            int cantDetalles = 1;
            int control = 0;

            while (control < cantDetalles)
            {

                table.AddCell(new Phrase(evento.NombreEvento, font_celdas));
                table.AddCell(new Phrase(participante.Nombre, font_celdas));
                table.AddCell(new Phrase(proporcion.ProporcionParticipante.ToString(), font_celdas));
                table.AddCell(new Phrase(apuesta.Monto.ToString(), font_celdas));
                table.AddCell(new Phrase(apuesta.PagoAsociado.FormaPagoAsociado.Nombre, font_celdas));
                control++;
            }

            document.Add(table);

            document.Add(new Paragraph("\n\r"));

            document.Add(new Paragraph("Monto total de la Factura:  ................................................................................... " + apuesta.Monto + " " + usuario.Divisa));
            document.Add(new Paragraph("\n\r"));

            Paragraph final = new Paragraph("GRACIAS POR APOSTAR EN KAMALDE \n SE ACABO LO QUE QUEDABA");
            final.Alignment = iTextSharp.text.Image.ALIGN_CENTER;

            document.Add(final);
            // Cierra el PDF creado.
            document.Close();


            // Se crean los datos y el mansaje del correo.
            System.Net.Mail.MailMessage correo = new System.Net.Mail.MailMessage();

            correo.From = new System.Net.Mail.MailAddress("kamalde.services@gmail.com", "Kamalde", System.Text.Encoding.UTF8);
            correo.To.Add(usuario.CorreoElectronico);
            correo.Subject = "Factura de su ultima apuesta  en Kamalde";
            correo.SubjectEncoding = System.Text.Encoding.ASCII;


            correo.Body = "Gracias por realizar su apuesta en Kamalde \n \r " +
                         "En el archivo adjunto encontrara su factura con los datos de su apuesta \n \r " +
                        "Fecha y Hora: " + DateTime.Now; ;

            correo.SubjectEncoding = System.Text.Encoding.Default;
            correo.IsBodyHtml = false;
            correo.Priority = System.Net.Mail.MailPriority.Normal;

            System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient();

            smtp.Host = "smtp.gmail.com";
            smtp.Port = 587;
            smtp.Credentials = new System.Net.NetworkCredential("kamalde.services@gmail.com", "barroeta");
            smtp.EnableSsl = true;

            //Se adjunta el archivo 
            Attachment data = new Attachment(ruta, MediaTypeNames.Application.Octet);
            ContentDisposition disposition = data.ContentDisposition;
            disposition.CreationDate = System.IO.File.GetCreationTime(ruta);
            disposition.ModificationDate = System.IO.File.GetLastWriteTime(ruta);
            disposition.ReadDate = System.IO.File.GetLastAccessTime(ruta);
            correo.Attachments.Add(data);

            try
            {
                smtp.Send(correo);
            }
            catch (Exception ex)
            {
                //ex.Message;
            }
        }
    }
}
